package com.hejia.alauda.utils;

import static com.hejia.alauda.utils.Utils.isAndroid;
import static com.hejia.alauda.utils.Utils.isIOS;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.replace;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.apache.commons.lang3.StringUtils.split;
import static org.apache.commons.lang3.StringUtils.substring;
import static org.springframework.util.CollectionUtils.arrayToList;
import static org.apache.commons.lang3.time.DateFormatUtils.*;
import static org.apache.commons.lang3.time.DateUtils.addDays;
import static org.apache.commons.lang3.time.DateUtils.setHours;
import static org.apache.commons.lang3.time.DateUtils.setMinutes;
import static org.apache.commons.lang3.time.DateUtils.setSeconds;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class Utils {
	
	public static final List<Runnable> taskList = new ArrayList<Runnable>();
	
	public static final List<String> NON_PERFORMING_ASSETS_TAG = arrayToList(new String[]{"满标起息","可提前还款"}); //不良资产的产品标签
	public static final List<String> ACCEPTANCE_BILL_TAG = arrayToList(new String[]{"满标起息","银行承兑"}); //票据产品的标签
	public static final List<String> QIANGUNFAN_TAG = arrayToList(new String[]{"满标起息","每月赎回"}); //钱滚翻的标签
	
	public static final int REGISTER_CREDITS = 500;
	public static final int BIND_CARD_CREDITS= 1500;
	public static final int FIRST_BUY_CREDITS = 18000;
	public static final int WASU_FIRST_BUY_CREDITS = 48000;
	
	public static final int FINANCIAL_10000 = 320;
	public static final int FINANCIAL_20000 = 25;
	public static final int FINANCIAL_50000 = 20;
	public static final int FINANCIAL_100000 = 5;
	
	public static long BONUS_START_DATE = 1422720000000L;//2015-02-01T00:00:00
	public static long TIME_2015_02_15 = 1423929600000L;
	public static long TIME_2015_02_18 = 1424188800000L;
	public static long TIME_2015_02_26 = 1424880000000L;
	public static long TIME_2015_02_27 = 1424966400000L;
	
	public static long TIME_2015_03_12_10_30_00 = 1426127400000L;
	public static long TIME_2015_03_12_15_00_00 = 1426143600000L;
	
	public static long TIME_2015_03_13_10_30_00 = 1426213800000L;
	public static long TIME_2015_03_13_15_00_00 = 1426230000000L;
	
	public static long TIME_2015_03_14 = 1426262400000L;
	public static long TIME_2015_03_18 = 1426608000000L;
	
	/*活动时间：快聚财加油站 致月底流量不够的你 2015年3月28日~3月31日*/
	public static long TIME_2015_03_28 = 1427439600000L;
	public static long TIME_2015_04_01 = 1427817600000L;
	
	/*活动时间：关注合家金融公众号，抢20元流量包，先到先得！ 2015年4月15日~2015年5月15日*/
	public static long TIME_2015_04_15 = 1429027200000L;
//	public static long TIME_2015_04_15 = 1429059600000L;
	public static long TIME_2015_04_22 = 1429632000000L;
	
	public static final String UTF_8 = org.apache.commons.codec.CharEncoding.UTF_8;
	
	public static final String MYSQL_DATE_FORMAT = "DATE_FORMAT(%s, \'%%Y-%%m-%%d\')";
	public static final String[] CHANNELS = new String[]{"华数","快客","TCL"};
	
	public static String redenvelopeEndTime = null;
	
	static volatile ObjectMapper objectMapper = null;
	
	private Utils(){}
	
	public static SimpleDateFormat format = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
			
	public static String formatDateTime(Date date) {
		return replace(ISO_DATETIME_FORMAT.format(date),"T"," ");
	}
	
	public static String formatDateTime_i18n(Date date) {
		return ISO_DATETIME_FORMAT.format(date);
	}
	
	public static String formatDate(Date date) {
		return ISO_DATE_FORMAT.format(date);
	}
	
	public static String formatDateTime(Calendar calendar) {
		return replace(ISO_DATETIME_FORMAT.format(calendar),"T"," ");
	}
	
	public static String formatDateTime_i18n(Calendar calendar) {
		return ISO_DATETIME_FORMAT.format(calendar);
	}
	
	public static String formatDate(Calendar calendar) {
		return ISO_DATE_FORMAT.format(calendar);
	}
	
	public static String translateDate(String date) {
//		String str = formatDate(date);
		String[] strs = split(date, '-');
		return strs[0] + "年" + (strs[1].startsWith("0")?substring(strs[1],-1):strs[1]) + "月" + (strs[2].startsWith("0")?substring(strs[2],-1):strs[2]) + "日";
	}
	
	public static String getServerName(String url) {
		if (isNotBlank(url)) {
			if (url.startsWith("http://")) {
				return url.substring(7);
			} else if (url.startsWith("https://")) {
				return url.substring(8);
			}
		}
		return url;
	}

	public static boolean isSendRedEnvelope() {
		String now = format.format(new Date());
//		System.out.println(redenvelopeEndTime);
		return now.compareTo(redenvelopeEndTime) < 0;
	}

	/**
	 * 对对象中对String字符串属性过滤空格
	 * 
	 * @param obj
	 * @return
	 */
	public static Object objectTrim(Object obj) {
		JSONObject json = JSON.parseObject(JSON.toJSONString(obj));
		Iterator<String> iterator = json.keySet().iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();

			if (json.get(key) != null) {
				String value = json.get(key).toString().trim();
				json.put(key, value);
			}
		}
		obj = JSONObject.parseObject(json.toJSONString(), obj.getClass());

		return obj;
	}
	/**
	 * 获取外部UserID
	 * @param id
	 * @return
	 */
	public static String getExternal(Long id) {
		return ((id * 113)^0x000353)+"";
	}
	
	/**
	 * 获取异常日志
	 * @param ex
	 * @return
	 */
	public static String getExceptionLog(Exception ex) {
		StringBuffer sb = new StringBuffer();

		sb.append(ex.getClass().getName() + ":" + ex.getMessage() + "\n");
		StackTraceElement[] ste = ex.getStackTrace();
		for (int i = 0; ste != null && i < ste.length; i++) {
			sb.append("at " + ste[i].getClassName() + "."
					+ ste[i].getMethodName() + "(" + ste[i].getFileName() + ":"
					+ ste[i].getLineNumber() + ")\n");
		}
		return sb.toString();
	}
	
	public static String toJSON(Object obj){
		ObjectMapper mapper = new ObjectMapper();
		String json = "";
		try {
			json = mapper.writer().writeValueAsString(obj == null ? new java.util.HashMap() : obj);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}
	
	/**
	 * 获取访问者IP
	 * 
	 * 在一般情况下使用Request.getRemoteAddr()即可，但是经过nginx等反向代理软件后，这个方法会失效。
	 * 
	 * 本方法先从Header中获取X-Real-IP，如果不存在再从X-Forwarded-For获得第一个IP(用,分割)，
	 * 如果还不存在则调用Request .getRemoteAddr()。
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Real-IP");
		if (!isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			return ip;
		}
		ip = request.getHeader("X-Forwarded-For");
		if (!isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			// 多次反向代理后会有多个IP值，第一个为真实IP。
			int index = ip.indexOf(',');
			if (index != -1) {
				return ip.substring(0, index);
			} else {
				return ip;
			}
		} else {
			return request.getRemoteAddr();
		}
	}
	
	public static ObjectMapper getInstance(){
		if (objectMapper==null){
			synchronized (ObjectMapper.class) {
				if (objectMapper==null){
					objectMapper = new ObjectMapper();
				}
			}
		}
		return objectMapper;
	}
	
	public static Map<String,Object> readValue(String content) {
		try {
			return getInstance().readValue(content, Map.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return java.util.Collections.EMPTY_MAP;
	}
	
	public static Object readValue(String content,Class valueType) {
		try {
			return getInstance().readValue(content, valueType);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return java.util.Collections.EMPTY_MAP;
	}
	
//	public static CreditTool getCreditTool(){
//		if (creditTool==null){
//			//正式应用
//			creditTool = new CreditTool("C4btVnrarNQPXBeF8gL79QydcSN","2PQChYasbReBkYf5PEkhiYrotLrv");
//			//演示应用
////			creditTool = new CreditTool("28TNXJ8uCi8ARPZDHAo3Qg21hGxW", "45noFJDDRM7X6QGKnomyjxcCF9S7");
//		}
//		return creditTool;
//	}
	
	public static boolean isCredit51(String openid){
		 return isNotBlank(openid) && !trimToEmpty(openid).equalsIgnoreCase("${openid}") ? true : false;
	}
	
	public static void main(String[] args) throws Exception{
		for(int i=0;i<2;i++)
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					HttpRequest.httpGet("http://127.0.0.1:8080/test/test.json", null);
				}
			}).start();
	}
	
	public static Date getNextDayZero() {
		return setSeconds(setMinutes(setHours(addDays(new Date(),1),0),0),0);
	}
	
	/**
	 * 
	 * @param active 是否活跃用户（即老用户）
	 * @return
	 */
	public static Integer getBonus(int min, int max) {
		Random seed = new Random();
		int[] pool = new int[max - min + 1];
		for(int i = min;i <= max;i++){
			pool[i - min] = i;
		}
		int total = 0, r = 0, n = 1;
		for(int i=0;i<n;i++) {
			total += pool[seed.nextInt(pool.length)];
		}
		return total/n;
	}
	
	public static BigDecimal getIncrementInterestRate(BigDecimal base,BigDecimal increment,BigDecimal max) {
		BigDecimal interestRate = new BigDecimal("0");
		if (base != null && increment != null && max != null) {
			BigDecimal temp = base.add(increment);
			interestRate = temp.compareTo(max) > 0 ? max : temp;
		}
		return interestRate;
	}
	
	public static boolean isAndroid(String platform) {
		return "Android".equalsIgnoreCase(platform);
	}
	
	public static boolean isIOS(String platform) {
		return "IOS".equalsIgnoreCase(platform);
	}
	
	public static boolean isH5(String platform){
		return !(isAndroid(platform) || isIOS(platform));
	}
	
	public static boolean isVersion10(String platform, String version) {
		return (isIOS(trimToEmpty(platform)) && trimToEmpty(version).compareTo("1.0")>=0) || (isAndroid(trimToEmpty(platform)) && trimToEmpty(version).compareTo("1")>=0);
	}
	
	//public static boolean isVersion18(String platform, String version) {
	//	return (isIOS(trimToEmpty(platform)) && trimToEmpty(version).compareTo("1.80")>=0) || (isAndroid(trimToEmpty(platform)) && trimToEmpty(version).compareTo("30")>=0);
	//}
	
	//public static boolean isVersion19(String platform, String version) {
	//	return (isIOS(trimToEmpty(platform)) && trimToEmpty(version).compareTo("1.90")>=0) || (isAndroid(trimToEmpty(platform)) && trimToEmpty(version).compareTo("40")>=0);
	//}

	public static String digitUppercase(double n){
        String fraction[] = {"角", "分"};
        String digit[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
        String unit[][] = {{"元", "万", "亿"},
                     {"", "拾", "佰", "仟"}};
 
        String head = n < 0? "负": "";
        n = Math.abs(n);
         
        String s = "";
        for (int i = 0; i < fraction.length; i++) {
            s += (digit[(int)(Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
        }
        if(s.length()<1){
            s = "整";    
        }
        int integerPart = (int)Math.floor(n);
 
        for (int i = 0; i < unit[0].length && integerPart > 0; i++) {
            String p ="";
            for (int j = 0; j < unit[1].length && n > 0; j++) {
                p = digit[integerPart%10]+unit[1][j] + p;
                integerPart = integerPart/10;
            }
            s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
        }
        return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
    }
}
